package com.yifi.common;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;

import net.sf.json.JSONObject;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;

public class SysUtil {

	public static String getGuid() {

		return UUID.randomUUID().toString();
	}

	public static String setWinPara(String winstr, String parastr) {
		winstr += (winstr.indexOf("?") > 0) ? "&" : "?";// 是否存在参数
		winstr += parastr;
		return winstr;
	}

	// 补足代码位数
	public static String getFillNum(String num, int len) {
		while (num.length() < len) {
			num = "0" + num;
		}
		return num;
	}

	public static List<Record> getListDDL(String sql, String textField, String valueField, String ftext,
			String fvalue) {
		List<Record> listRecord = Db.find(sql);
		Record record = new Record();
		record.set(valueField, fvalue);
		record.set(textField, ftext);
		record.set("selected", true);
		listRecord.add(0, record);
		return listRecord;
	}

	public static List<Record> getListDDL(String sql, String textField, String valueField) {
		List<Record> listRecord = Db.find(sql);
		if (listRecord.size() > 0) {
			listRecord.get(0).set("selected", true);
		}
		return listRecord;
	}

	// 格式化日期
	public static String GetFormatDate(Date date, String format) {
		// "yyyy-MM-dd HH:mm:ss"
		// "yyyy-MM-01"
		if (date == null) {
			return "";
		}
		return new SimpleDateFormat(format).format(date);
	}

	public static String GetFormatDateTime(Date date) {
		if (date == null) {
			return "";
		}
		return GetFormatDate(date, "yyyy-MM-dd HH:mm:ss");
	}

	public static String GetNowDate(String format) {
		Date date = DBHelper.GetDateNow();
		return new SimpleDateFormat(format).format(date);
	}

	// 输出前端提示信息
	public static String ResultMsg(boolean success, String msg) {
		Map<String, Object> rs = new HashMap<String, Object>();
		rs.put("success", success);
		rs.put("msg", msg);
		return JSONObject.fromObject(rs).toString();
	}

	public static String ResultMsg(Map<String, Object> rs) {
		return JSONObject.fromObject(rs).toString();
	}

	/**
	 * 将字符串中的中文转化为拼音,其他字符不变
	 * 
	 * @param inputString
	 * @return
	 */
	public static String getPingYin(String inputString) {
		HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
		format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		format.setVCharType(HanyuPinyinVCharType.WITH_V);

		char[] input = inputString.trim().toCharArray();
		String output = "";

		try {
			for (int i = 0; i < input.length; i++) {
				if (Character.toString(input[i]).matches("[\\u4E00-\\u9FA5]+")) {
					String[] temp = PinyinHelper.toHanyuPinyinStringArray(input[i], format);
					output += temp[0];
				} else
					output += Character.toString(input[i]);
			}
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			e.printStackTrace();
		}
		return output;
	}

	/**
	 * 获取汉字串拼音首字母，英文字符不变
	 * 
	 * @param chinese 汉字串
	 * @return 汉语拼音首字母
	 */
	public static String getFirstSpell(String chinese) {
		StringBuffer pybf = new StringBuffer();
		char[] arr = chinese.toCharArray();
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] > 128) {
				try {
					String[] temp = PinyinHelper.toHanyuPinyinStringArray(arr[i], defaultFormat);
					if (temp != null) {
						pybf.append(temp[0].charAt(0));
					}
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			} else {
				pybf.append(arr[i]);
			}
		}
		return pybf.toString().replaceAll("\\W", "").trim().toUpperCase();
	}

	/**
	 * 获取汉字串拼音，英文字符不变
	 * 
	 * @param chinese 汉字串
	 * @return 汉语拼音
	 */
	public static String getFullSpell(String chinese) {
		StringBuffer pybf = new StringBuffer();
		char[] arr = chinese.toCharArray();
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] > 128) {
				try {
					pybf.append(PinyinHelper.toHanyuPinyinStringArray(arr[i], defaultFormat)[0]);
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			} else {
				pybf.append(arr[i]);
			}
		}
		return pybf.toString();
	}

	// ====合计小计======
	public static List<String> GetListStr(String... strs) {
		List<String> listStr = new ArrayList<String>();
		for (int i = 0; i < strs.length; i++) {
			listStr.add(strs[i]);
		}
		return listStr;
	}

	// 合计
	public static Map GetListHJ(List<Record> listRecord, String f_text, List<String> List_f_nums) {
		return GetListHJ(listRecord, f_text, List_f_nums, null);
	}

	// 小计合计
	/**
	 * 小计合计
	 * 
	 * @param listRecord  原始数据
	 * @param f_text      放[小计][合计]标签的字段
	 * @param List_f_nums 需要统计的数字列集合
	 * @param List_f_keys 用于小计的分组关键字字段集合
	 * @return 用于easyui带foot合计的数据
	 */
	public static Map GetListHJ(List<Record> listRecord, String f_text, List<String> List_f_nums,
			List<String> List_f_keys) {
		if (List_f_nums.size() == 1 && List_f_nums.get(0).equals("")) {
			List_f_nums.clear();// 数字列中只有一个空字段，则返回一个空的合计列,合计放在前台处理
		}
		boolean isxj = (List_f_keys != null);// 是否小计,小计需要分组关键字字段

		List<Record> listR_num = new ArrayList<Record>();
		for (String f_num : List_f_nums)// 数字列 [数字字段，小计数，合计数]
		{
			Record r_num = new Record();
			r_num.set("f_num", f_num);
			r_num.set("xj", new BigDecimal(0));
			r_num.set("hj", new BigDecimal(0));
			listR_num.add(r_num);
		}

		Map<String, Object> mapdata = new HashMap<String, Object>();
		// mapdata.put("total", listRecord.size());
		int rowsize = listRecord.size();
		int rowc_xj = 1;// 小计
		List<Record> listR_xj = new ArrayList<Record>();
		for (Record r : listRecord) {
			int rowindex = listRecord.indexOf(r);// 本行号
			int rowindex_n = rowindex + 1;// 下行号
			for (Record r_num : listR_num)// 数字列赋值小计合计
			{
				String f_num = r_num.getStr("f_num");

				/*
				 * Double f_num_d= DBHelper.GetDouble(r, f_num); Double xj=
				 * r_num.getDouble("xj")+f_num_d; r_num.set("xj", xj); Double hj=
				 * r_num.getDouble("hj")+f_num_d; r_num.set("hj", hj);
				 */
				BigDecimal f_num_d = r.getBigDecimal(f_num);
				f_num_d = (f_num_d != null) ? f_num_d : new BigDecimal(0);

				BigDecimal xj = r_num.getBigDecimal("xj").add(f_num_d);
				r_num.set("xj", xj);
				BigDecimal hj = r_num.getBigDecimal("hj").add(f_num_d);
				r_num.set("hj", hj);
			}

			if (isxj) {
				int addindex = rowindex + rowc_xj;
				boolean islast = false;// 是否组中最后一行
				if (rowindex == (rowsize - 1))// 数据最后行
				{
					islast = true;
				} else// 检测下行数据差异
				{
					for (String f_key : List_f_keys)// 关键字
					{
						String f_value = r.getStr(f_key);
						String f_value_n = listRecord.get(rowindex_n).getStr(f_key);
						if (!f_value_n.equals(f_value))// 组中
						{
							islast = true;
							break;
						}
					}
				}
				if (islast)// 生成小计
				{
					Record r_xj = new Record();
					r_xj.set("isfoot", true);
					if (!f_text.equals("")) {
						r_xj.set(f_text, "[小计]:");
					}
					for (Record r_num : listR_num)// 数字列
					{
						String f_num = r_num.getStr("f_num");
						r_xj.set(f_num, r_num.getBigDecimal("xj"));
						r_num.set("xj", new BigDecimal(0));
					}
					r_xj.set("addindex", addindex);
					listR_xj.add(r_xj);

					rowc_xj++;
				}
			}
		}
		if (isxj) {
			for (Record r : listR_xj)// 小计行
			{
				listRecord.add(r.getInt("addindex"), r);
			}
		}

		List<Record> listFoot = new ArrayList<Record>();
		Record footR = new Record();
		footR.set("isfoot", true);
		if (!f_text.equals("")) {
			footR.set(f_text, "[合计]:");
		}
		for (Record r_num : listR_num)// 数字列
		{
			String f_num = r_num.getStr("f_num");
			footR.set(f_num, r_num.getBigDecimal("hj"));
		}
		listFoot.add(footR);

		mapdata.put("rows", listRecord);
		mapdata.put("footer", listFoot);
		return mapdata;
	}

	public static List<Record> GetListHJ1(List<Record> listRecord, String f_text, List<String> List_f_nums,
			List<String> List_f_keys) {
		if (List_f_nums.size() == 1 && List_f_nums.get(0).equals("")) {
			List_f_nums.clear();// 数字列中只有一个空字段，则返回一个空的合计列,合计放在前台处理
		}
		boolean isxj = (List_f_keys != null);// 是否小计,小计需要分组关键字字段

		List<Record> listR_num = new ArrayList<Record>();
		for (String f_num : List_f_nums)// 数字列 [数字字段，小计数，合计数]
		{
			Record r_num = new Record();
			r_num.set("f_num", f_num);
			r_num.set("xj", new BigDecimal(0));
			r_num.set("hj", new BigDecimal(0));
			listR_num.add(r_num);
		}

		Map<String, Object> mapdata = new HashMap<String, Object>();
		// mapdata.put("total", listRecord.size());
		int rowsize = listRecord.size();
		int rowc_xj = 1;// 小计
		List<Record> listR_xj = new ArrayList<Record>();
		for (Record r : listRecord) {
			int rowindex = listRecord.indexOf(r);// 本行号
			int rowindex_n = rowindex + 1;// 下行号
			for (Record r_num : listR_num)// 数字列赋值小计合计
			{
				String f_num = r_num.getStr("f_num");

				/*
				 * Double f_num_d= DBHelper.GetDouble(r, f_num); Double xj=
				 * r_num.getDouble("xj")+f_num_d; r_num.set("xj", xj); Double hj=
				 * r_num.getDouble("hj")+f_num_d; r_num.set("hj", hj);
				 */
				BigDecimal f_num_d = r.getBigDecimal(f_num);
				f_num_d = (f_num_d != null) ? f_num_d : new BigDecimal(0);

				BigDecimal xj = r_num.getBigDecimal("xj").add(f_num_d);
				r_num.set("xj", xj);
				BigDecimal hj = r_num.getBigDecimal("hj").add(f_num_d);
				r_num.set("hj", hj);
			}

			if (isxj) {
				int addindex = rowindex + rowc_xj;
				boolean islast = false;// 是否组中最后一行
				if (rowindex == (rowsize - 1))// 数据最后行
				{
					islast = true;
				} else// 检测下行数据差异
				{
					for (String f_key : List_f_keys)// 关键字
					{
						String f_value = r.getStr(f_key);
						String f_value_n = listRecord.get(rowindex_n).getStr(f_key);
						if (!f_value_n.equals(f_value))// 组中
						{
							islast = true;
							break;
						}
					}
				}
				if (islast)// 生成小计
				{
					Record r_xj = new Record();
					r_xj.set("isfoot", true);
					if (!f_text.equals("")) {
						r_xj.set(f_text, "[小计]:");
					}
					for (Record r_num : listR_num)// 数字列
					{
						String f_num = r_num.getStr("f_num");
						r_xj.set(f_num, r_num.getBigDecimal("xj"));
						r_num.set("xj", new BigDecimal(0));
					}
					r_xj.set("addindex", addindex);
					listR_xj.add(r_xj);

					rowc_xj++;
				}
			}
		}
		if (isxj) {
			for (Record r : listR_xj)// 小计行
			{
				listRecord.add(r.getInt("addindex"), r);
			}
		}

		List<Record> listFoot = new ArrayList<Record>();
		Record footR = new Record();
		footR.set("isfoot", true);
		if (!f_text.equals("")) {
			footR.set(f_text, "[合计]:");
		}
		for (Record r_num : listR_num)// 数字列
		{
			String f_num = r_num.getStr("f_num");
			footR.set(f_num, r_num.getBigDecimal("hj"));
		}
		listFoot.add(footR);

		// mapdata.put("rows", listRecord);
		// mapdata.put("footer", listFoot);
		return listFoot;
	}

	// ====合计小计end======

	public static Map<String, Object> paginateWithSum(int pageNumber, int pageSize, String select,
			String sqlExceptSelect, String f_text, List<String> List_f_nums) {
		Page<Record> pageR = Db.paginate(pageNumber, pageSize, select, sqlExceptSelect);

		Map<String, Object> mapdata = new HashMap<>();
		mapdata.put("total", pageR.getTotalRow());
		mapdata.put("rows", pageR.getList());

		List<Record> listFoot = new ArrayList<Record>();
		Record footR = new Record();

		if (List_f_nums.size() > 0) {
			String sql = "select ";
			for (String str : List_f_nums) {
				sql += " sum(" + str + ") as " + str + " ,";
			}
			sql = sql.substring(0, sql.length() - 1);
			footR = Db.findFirst(sql + sqlExceptSelect);
		}

		footR.set("isfoot", true);
		if (!f_text.equals("")) {
			footR.set(f_text, "[合计]:");
		}

		listFoot.add(footR);

		mapdata.put("footer", listFoot);

		return mapdata;
	}

	/**
	 * 向指定 URL 发送POST方法的请求
	 * 
	 * @param url   发送请求的 URL
	 * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
	 * @return 所代表远程资源的响应结果
	 */
	public static String sendPost(String url, String param) {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常！" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}

	// 由数据库user字符串生成sql字符串
	// ,0001,0002,转为'','0001','0002'
	public static String getUserSql(String strUser) {
		String cusers = "''";
		String[] users = strUser.split(",");
		for (String user : users) {
			cusers += ",'" + user + "'";
		}
		return cusers;
	}

	// 操作日志
	public static boolean SysLog(String log_type, String log_content, HttpServletRequest request) {

		Record record = new Record();
		record.set("id", SysUtil.getGuid());
		record.set("m_id", "");
		record.set("log_type", log_type);
		record.set("log_content", log_content);
		record.set("log_user", request.getSession().getAttribute("Gs_user"));
		record.set("log_uname", request.getSession().getAttribute("Gs_uname"));
		record.set("log_ip", request.getRemoteAddr());
		record.set("log_date", DBHelper.GetDateNow());
		record.set("log_flag", "1");// 特殊标记用

		return DBHelper.ExecNonQuery("mis_log", "id", record, false);
	}

	public static Date AddDate(Date dt, int addnum, int calendar) {
		Calendar rightNow = Calendar.getInstance();
		rightNow.setTime(dt);
		// rightNow.add(Calendar.YEAR,-1);//日期减1年
		// rightNow.add(Calendar.MONTH,3);//日期加3个月
		rightNow.add(calendar, addnum);// 日期加10天
		// return rightNow.getTime();
		return new java.sql.Time(rightNow.getTimeInMillis());
	}

	public static Date AddYears(Date dt, int addnum) {
		return AddDate(dt, addnum, Calendar.YEAR);
	}

	public static Date AddDays(Date dt, int addnum) {
		return AddDate(dt, addnum, Calendar.DATE);
	}

	public static Date AddHours(Date dt, int addnum) {
		return AddDate(dt, addnum, Calendar.HOUR);
	}

	public static Date AddMinute(Date dt, int addnum) {
		return AddDate(dt, addnum, Calendar.MINUTE);
	}

	public static Date AddSecond(Date dt, int addnum) {
		return AddDate(dt, addnum, Calendar.SECOND);
	}

	public static Date ConvertDate(String strdt) {

		Date newdate = new SimpleDateFormat("yyyy-MM-dd").parse(strdt, new ParsePosition(0));
		return new java.sql.Time(newdate.getTime());
	}

	public static Date ConvertDateTime(String strdt) {

		Date newdate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(strdt, new ParsePosition(0));
		return new java.sql.Time(newdate.getTime());
	}

	/*
	 * 将时间戳转换为时间
	 */
	public static String stampToDate(String s) {
		String res;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long lt = new Long(s);
		Date date = new Date(lt);
		res = simpleDateFormat.format(date);
		return res;
	}

	public static String get_ys_token() {

		// 萤石云开放平台:https://open.ys7.com/cn

		// String accessToken
		// ="at.8jerjkvw9nffeu9y0d8xrakg5aal8a0k-8hesjesrw0-1k7e9hs-irlmznw00";
		String accessToken = DBHelper
				.GetString("select c03 from sys_option where c03 is not null and  date_add(now(), interval 3 day)<d04");
		if (accessToken.equals("")) {
			String appKey = DBHelper.GetString("select c01 from sys_option");// 42bf3ff3cbe94383a856bd4720a60a17
			String appSecret = DBHelper.GetString("select c02 from sys_option");// 16e1d73f3700889d2e0548914c17405d
			String param = "appKey=" + appKey + "&appSecret=" + appSecret;
			String url = "https://open.ys7.com/api/lapp/token/get";

			String result = SysUtil.sendPost(url, param);
			JSONObject jsonResult = JSONObject.fromObject(result);

			if (jsonResult.has("data")) {
				JSONObject jsonResult_data = JSONObject.fromObject(jsonResult.get("data"));
				accessToken = jsonResult_data.getString("accessToken");
				long expireTime = jsonResult_data.getLong("expireTime");// 到期时间戳
				Db.update("update sys_option set c03='" + accessToken + "',d04='"
						+ SysUtil.stampToDate(String.valueOf(expireTime)) + "'");
			}
		}
		return accessToken;
	}

	// 分钟数 格式化为 XX时XX分
	public static String format_minute(String c_minute) {
		String c_sj = "";
		if (c_minute != "") {
			int n_minute = Integer.valueOf(c_minute);
			if (n_minute >= 60)// 1小时以上
			{
				c_sj = n_minute / 60 + "时";
			}
			c_sj += n_minute % 60 + "分";
		}
		return c_sj;
	}

	public static double fmtDouble(double val, int prec) {
		BigDecimal bg = new BigDecimal(val);
		return bg.setScale(prec, BigDecimal.ROUND_HALF_UP).doubleValue();

	}

}
